package sui.utils.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

/**
 * <p>
 * Description: HTTP客户端工具类
 * </p>
 * @author XQF SUI
 * @created 2016年10月10日 下午5:25:12
 * @version 1.0
 */
public class HttpClientUtils {

    private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

    /**
     * <p>
     * Desc: GET请求
     * </p>
     * @author XQF SUI
     * @created 2016年10月11日 上午9:53:41
     * @param url
     * @param paramJson
     * @return
     * @throws URISyntaxException 
     * @throws IOException 
     * @throws UnsupportedEncodingException 
     * @throws ParseException 
     * @throws ClientProtocolException 
     */
    public static String get(String url, String paramJson) throws ClientProtocolException, ParseException,
            UnsupportedEncodingException, IOException, URISyntaxException {
        logger.info("创建HTTP GET请求...请求地址[ {} ], 参数[ {} ]", url, paramJson);
        return invoke(createHTTPClient(), getForm(url, paramJson));
    }

    /**
     * <p>
     * Desc: POST请求
     * </p>
     * @author XQF SUI
     * @created 2016年10月10日 下午5:49:04
     * @param url
     * @param paramJson
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String post(String url, String paramJson) throws ClientProtocolException, IOException {
        logger.info("创建HTTP POST请求...请求地址[ {} ], 参数[ {} ]", url, paramJson);
        return invoke(createHTTPClient(), postForm(url, paramJson));
    }

    /**
     * <p>
     * Desc: 执行
     * </p>
     * @author XQF SUI
     * @created 2016年10月10日 下午5:49:19
     * @param client
     * @param httpPost
     * @return
     * @throws IOException 
     * @throws ClientProtocolException 
     */
    public static String invoke(CloseableHttpClient client, HttpUriRequest httpPost)
            throws ClientProtocolException, IOException {
        logger.info("执行请求...");
        return getEntity(client.execute(httpPost));
    }

    /**
     * <p>
     * Desc: 获取返回参数
     * </p>
     * @author XQF SUI
     * @created 2016年10月10日 下午5:53:48
     * @param execute
     * @return
     * @throws IOException 
     * @throws ParseException 
     */
    private static String getEntity(CloseableHttpResponse execute) throws ParseException, IOException {
        logger.info("获取返回参数...");

        HttpEntity entity = execute.getEntity();

        if (entity == null) {
            logger.info("返回参数为空");
            return null;
        }

        String result = EntityUtils.toString(entity);

        logger.info("返回参数为[ {} ]", result);

        return result;
    }

    /**
     * <p>
     * Desc: 创建HTTP POST
     * </p>
     * @author XQF SUI
     * @created 2016年10月10日 下午5:50:25
     * @param url
     * @param paramJson
     * @return
     * @throws UnsupportedEncodingException
     */
    private static HttpUriRequest postForm(String url, String paramJson) throws UnsupportedEncodingException {
        logger.info("创建HTTP POST...");

        HttpPost httpPost = new HttpPost(url);

        httpPost.addHeader("content-type", "application/json");
        
        if (StringUtils.isNotBlank(paramJson)) {
            httpPost.setEntity(new UrlEncodedFormEntity(initParams(paramJson), "UTF-8"));
        }

        return httpPost;
    }

    /**
     * <p>
     * Desc: 初始化参数
     * </p>
     * @author XQF SUI
     * @created 2016年10月11日 上午10:10:26
     * @param paramJson
     * @return
     */
    private static List<NameValuePair> initParams(String paramJson) {
        logger.info("初始化参数...");
        
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        @SuppressWarnings("unchecked")
        Map<String, Object> paramMap = JSON.parseObject(paramJson, HashMap.class);

        for (String key : paramMap.keySet()) {
            if (paramMap.get(key) != null) {
                params.add(new BasicNameValuePair(key, paramMap.get(key).toString()));
            }
        }

        return params;
    }

    /**
     * <p>
     * Desc: 初始化参数
     * </p>
     * @author XQF SUI
     * @created 2016年10月11日 上午9:58:23
     * @param url
     * @param paramJson
     * @return
     * @throws URISyntaxException 
     * @throws IOException 
     * @throws UnsupportedEncodingException 
     * @throws ParseException 
     */
    private static HttpUriRequest getForm(String url, String paramJson)
            throws URISyntaxException, ParseException, UnsupportedEncodingException, IOException {
        logger.info("创建HTTP GET...");

        if (StringUtils.isNotBlank(paramJson)) {
            // 设置参数
            url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(initParams(paramJson)));
        }

        return new HttpGet(url);
    }

    /**
     * <p>
     * Desc: 创建HTTP客户端
     * </p>
     * @author XQF SUI
     * @created 2016年10月10日 下午5:50:45
     * @return
     */
    public static CloseableHttpClient createHTTPClient() {
        logger.info("创建HTTP客户端...");
        return HttpClientBuilder.create().setRetryHandler(new DefaultHttpRequestRetryHandler()).build();
    }
    
    public static void main(String[] args) throws ClientProtocolException, ParseException, UnsupportedEncodingException, IOException, URISyntaxException {
        
        String str = get("http://10.100.142.68:58080/id-web/services/id/getPoseidonUserId/1", null);

        System.out.println(str);
    }
}
